interface AnyObject {
  [key: string]: any;
}

interface ResponseData<T> {
  code: number;
  data: T;
  message: string;
}

const host = 'https://chat.miye009.com/api';

function getParams(data: AnyObject) {
  const arr: string[] = [];
  for (const key in data) {
    arr.push(`${key}=${data[key]}`);
  }
  return arr.join('&');
}

async function request(url: string, data: AnyObject, method: 'GET' | 'POST') {
  url = host + url;
  let params = '';
  if (method === 'GET') {
    params = getParams(data);
    url += '?' + params;
    params = '';
  } else {
    params = JSON.stringify(data);
  }
  const response = await fetch(url, {
    method,
    body: params,
    headers: {
      'Content-Type': 'application/json',
    },
  });
  return response.json();
}

async function sendRequest<T>(
  method: 'GET' | 'POST',
  ...args: any[]
): Promise<ResponseData<T>> {
  let [url, data, loading = ref(false)] = args;
  if (isRef(data)) {
    loading = data;
    data = {};
  }
  loading.value = true;
  let response: ResponseData<T> = {
    code: 500,
    message: '系统错误，请稍后重试',
    data: {} as T,
  };
  try {
    response = await request(url, data, method);
    if (response.code !== 200) {
      useMessage.error(response.message || '系统错误，请稍后重试');
      return Promise.reject(response);
    }
    return response;
  } catch (e) {
    useMessage.error('系统错误，请稍后重试');
  } finally {
    loading.value = false;
  }
  return Promise.reject(response);
}

export async function useGet<T>(
  url: string,
  data: AnyObject,
  loading: Ref<boolean>
): Promise<ResponseData<T>>;
export async function useGet<T>(
  url: string,
  loading: Ref<boolean>
): Promise<ResponseData<T>>;
export async function useGet<T>(
  url: string,
  data: AnyObject
): Promise<ResponseData<T>>;
export async function useGet<T>(url: string): Promise<ResponseData<T>>;

export async function useGet<T>(...args: any[]): Promise<ResponseData<T>> {
  return sendRequest('GET', ...args);
}

export async function usePost<T>(
  url: string,
  data: AnyObject,
  loading: Ref<boolean>
): Promise<ResponseData<T>>;
export async function usePost<T>(
  url: string,
  data: AnyObject
): Promise<ResponseData<T>>;
export async function usePost<T>(
  url: string,
  loading: Ref<boolean>
): Promise<ResponseData<T>>;
export async function usePost<T>(url: string): Promise<ResponseData<T>>;

export async function usePost<T>(...args: any[]): Promise<ResponseData<T>> {
  return sendRequest('POST', ...args);
}
